home *** CD-ROM | disk | FTP | other *** search
/ PC Format (PL) 2008 February / PC_Format_022008.iso / Internet / Mozilla Thunderbird wtyczki / lightning-0.7-tb-win.xpi / js / calWcapCalendar.js < prev    next >
Encoding:
JavaScript  |  2007-09-27  |  16.6 KB  |  468 lines

  1. /* -*- Mode: javascript; tab-width: 20; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
  2. /* ***** BEGIN LICENSE BLOCK *****
  3.  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
  4.  *
  5.  * The contents of this file are subject to the Mozilla Public License Version
  6.  * 1.1 (the "License"); you may not use this file except in compliance with
  7.  * the License. You may obtain a copy of the License at
  8.  * http://www.mozilla.org/MPL/
  9.  *
  10.  * Software distributed under the License is distributed on an "AS IS" basis,
  11.  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
  12.  * for the specific language governing rights and limitations under the
  13.  * License.
  14.  *
  15.  * The Original Code is Sun Microsystems code.
  16.  *
  17.  * The Initial Developer of the Original Code is
  18.  * Sun Microsystems, Inc.
  19.  * Portions created by the Initial Developer are Copyright (C) 2007
  20.  * the Initial Developer. All Rights Reserved.
  21.  *
  22.  * Contributor(s):
  23.  *   Daniel Boelzle <daniel.boelzle@sun.com>
  24.  *
  25.  * Alternatively, the contents of this file may be used under the terms of
  26.  * either the GNU General Public License Version 2 or later (the "GPL"), or
  27.  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
  28.  * in which case the provisions of the GPL or the LGPL are applicable instead
  29.  * of those above. If you wish to allow use of your version of this file only
  30.  * under the terms of either the GPL or the LGPL, and not to allow others to
  31.  * use your version of this file under the terms of the MPL, indicate your
  32.  * decision by deleting the provisions above and replace them with the notice
  33.  * and other provisions required by the GPL or the LGPL. If you do not delete
  34.  * the provisions above, a recipient may use your version of this file under
  35.  * the terms of any one of the MPL, the GPL or the LGPL.
  36.  *
  37.  * ***** END LICENSE BLOCK ***** */
  38.  
  39. var g_lastOnErrorTime = 0;
  40. var g_lastOnErrorNo = 0;
  41. var g_lastOnErrorMsg = null;
  42.  
  43. function calWcapCalendar(/*optional*/session, /*optional*/calProps) {
  44.     this.wrappedJSObject = this;
  45.     this.m_session = session;
  46.     this.m_calProps = calProps;
  47.     this.m_observers = new calListenerBag(Components.interfaces.calIObserver);
  48.     this.m_bSuppressAlarms = SUPPRESS_ALARMS;
  49. }
  50. calWcapCalendar.prototype = {
  51.     m_ifaces: [ calIWcapCalendar,
  52.                 calICalendar,
  53.                 Components.interfaces.calICalendarProvider,
  54.                 Components.interfaces.nsIInterfaceRequestor,
  55.                 Components.interfaces.nsIClassInfo,
  56.                 nsISupports ],
  57.     
  58.     // nsISupports:
  59.     QueryInterface: function calWcapCalendar_QueryInterface(iid) {
  60.         ensureIID(this.m_ifaces, iid); // throws
  61.         return this;
  62.     },
  63.     
  64.     // nsIClassInfo:
  65.     getInterfaces: function calWcapCalendar_getInterfaces(count) {
  66.         count.value = this.m_ifaces.length;
  67.         return this.m_ifaces;
  68.     },
  69.     get classDescription() {
  70.         return calWcapCalendarModule.WcapCalendarInfo.classDescription;
  71.     },
  72.     get contractID() {
  73.         return calWcapCalendarModule.WcapCalendarInfo.contractID;
  74.     },
  75.     get classID() {
  76.         return calWcapCalendarModule.WcapCalendarInfo.classID;
  77.     },
  78.     getHelperForLanguage: function calWcapCalendar_getHelperForLanguage(language) { return null; },
  79.     implementationLanguage: Components.interfaces.nsIProgrammingLanguage.JAVASCRIPT,
  80.     flags: 0,
  81.     
  82.     // nsIInterfaceRequestor:
  83.     getInterface: function calWcapCalendar_getInterface(iid, instance)
  84.     {
  85.         if (iid.equals(Components.interfaces.nsIAuthPrompt)) {
  86.             // use the window watcher service to get a nsIAuthPrompt impl
  87.             return getWindowWatcher().getNewAuthPrompter(null);
  88.         }
  89.         else if (iid.equals(Components.interfaces.nsIPrompt)) {
  90.             // use the window watcher service to get a nsIPrompt impl
  91.             return getWindowWatcher().getNewPrompter(null);
  92.         }
  93.         Components.returnCode = Components.results.NS_ERROR_NO_INTERFACE;
  94.         return null;
  95.     },
  96.     
  97.     toString: function calWcapCalendar_toString() {
  98.         var str = this.session.toString();
  99.         if (this.m_calId)
  100.             str += (", calId=" + this.calId);
  101.         else
  102.             str += ", default calendar";
  103.         return str;
  104.     },
  105.     notifyError: function calWcapCalendar_notifyError(err, suppressOnError)
  106.     {
  107.         if (getResultCode(err) == calIErrors.OPERATION_CANCELLED) {
  108.             return;
  109.         }
  110.         debugger;
  111.         var msg = logError(err, this);
  112.         if (!suppressOnError) {
  113.             this.notifyObservers(
  114.                 "onError",
  115.                 err instanceof Components.interfaces.nsIException
  116.                 ? [err.result, err.message] : [isNaN(err) ? -1 : err, msg]);
  117.         }
  118.     },
  119.     
  120.     // calICalendarProvider:
  121.     get prefChromeOverlay() {
  122.         return null;
  123.     },
  124.     // displayName attribute already part of calIWcapCalendar
  125.     createCalendar: function calWcapCalendar_createCalendar(name, url, listener) {
  126.         throw NS_ERROR_NOT_IMPLEMENTED;
  127.     },
  128.     deleteCalendar: function calWcapCalendar_deleteCalendar(calendar, listener) {
  129.         throw NS_ERROR_NOT_IMPLEMENTED;
  130.     },
  131.     getCalendar: function calWcapCalendar_getCalendar(url) {
  132.         throw NS_ERROR_NOT_IMPLEMENTED;
  133.     },
  134.     
  135.     // calICalendar:
  136.     mID: null,
  137.     get id() {
  138.         return this.mID;
  139.     },
  140.     set id(id) {
  141.         if (this.mID)
  142.             throw Components.results.NS_ERROR_ALREADY_INITIALIZED;
  143.         return (this.mID = id);
  144.     },
  145.  
  146.     get name() {
  147.         var name = getCalendarManager().getCalendarPref(this, "name");
  148.         if (!name) {
  149.             name = this.displayName;
  150.         }
  151.         return name;
  152.     },
  153.     set name(name) {
  154.         getCalendarManager().setCalendarPref(this, "name", name);
  155.         return name;
  156.     },
  157.     
  158.     get type() { return "wcap"; },
  159.     
  160.     m_superCalendar: null,
  161.     get superCalendar() {
  162.         return (this.m_superCalendar || this);
  163.     },
  164.     set superCalendar(cal) {
  165.         return (this.m_superCalendar = cal);
  166.     },
  167.     
  168.     m_bReadOnly: undefined,
  169.     get readOnly() {
  170.         // xxx todo:
  171.         // read-only if not logged in, this flag is tested quite
  172.         // early, so don't log in here if not logged in already...
  173.         return (this.m_bReadOnly ||
  174.                 !this.session.isLoggedIn ||
  175.                 // limit to write permission on components:
  176.                 !this.checkAccess(calIWcapCalendar.AC_COMP_WRITE) ||
  177.                 ((this.m_bReadOnly === undefined) && // has not been explicitly set
  178.                  !this.isOwnedCalendar));
  179.     },
  180.     set readOnly(bReadOnly) {
  181.         return (this.m_bReadOnly = bReadOnly);
  182.     },
  183.  
  184.     m_uri: null,
  185.     get uri() {
  186.         return this.m_uri;
  187.     },
  188.     set uri(thatUri) {
  189.         this.m_uri = thatUri.clone();
  190.         var path = thatUri.path;
  191.         var qmPos = path.indexOf("?");
  192.         if (qmPos != -1) {
  193.             var pos = path.indexOf("?calid=", qmPos);
  194.             if (pos != -1) {
  195.                 var start = (pos + "?calid=".length);
  196.                 var end = path.indexOf("&", start);
  197.                 this.m_calId = decodeURIComponent(
  198.                     path.substring(start, end == -1 ? path.length : end));
  199.             }
  200.         }
  201.         return this.uri;
  202.     },
  203.  
  204.     m_observers: null,
  205.     notifyObservers: function calWcapCalendar_notifyObservers(func, args) {
  206.         if (g_bShutdown)
  207.             return;
  208.         if (func == "onError") {
  209.             // xxx todo: hack
  210.             // suppress identical error bursts when multiple similar calls eg on getItems() fail.
  211.             var now = (new Date()).getTime();
  212.             if ((now - g_lastOnErrorTime) < 1000 &&
  213.                 (args[0] == g_lastOnErrorNo) &&
  214.                 (args[1] == g_lastOnErrorMsg)) {
  215.                 log("suppressing calIObserver::onError.", this);
  216.                 return;
  217.             }
  218.             g_lastOnErrorTime = now;
  219.             g_lastOnErrorNo = args[0];
  220.             g_lastOnErrorMsg = args[1];
  221.         }
  222.  
  223.         this.m_observers.notify(func, args);
  224.     },
  225.     addObserver: function calWcapCalendar_addObserver(observer) {
  226.         this.m_observers.add(observer);
  227.     },
  228.     removeObserver: function calWcapCalendar_removeObserver(observer) {
  229.         this.m_observers.remove(observer);
  230.     },
  231.     
  232.     // xxx todo: batch currently not used
  233.     startBatch: function calWcapCalendar_startBatch() {
  234.         this.notifyObservers("onStartBatch");
  235.     },
  236.     endBatch: function calWcapCalendar_endBatch() {
  237.         this.notifyObservers("onEndBatch");
  238.     },
  239.     
  240.     // xxx todo: rework like in
  241.     //           https://bugzilla.mozilla.org/show_bug.cgi?id=257428
  242.     m_bSuppressAlarms: false,
  243.     get suppressAlarms() {
  244.         return (this.m_bSuppressAlarms ||
  245.                 // writing lastAck does currently not work on readOnly cals,
  246.                 // so avoid alarms if not writable at all... discuss!
  247.                 // use m_bReadOnly here instead of attribute, because this
  248.                 // calendar acts read-only if not logged in
  249.                 this.m_bReadOnly ||
  250.                 // xxx todo: check write permissions in advance
  251.                 // alarms only for own calendars:
  252.                 // xxx todo: assume alarms if not logged in already
  253.                 (this.session.isLoggedIn && !this.isOwnedCalendar));
  254.     },
  255.     set suppressAlarms(bSuppressAlarms) {
  256.         return (this.m_bSuppressAlarms = bSuppressAlarms);
  257.     },
  258.     
  259.     get sendItipInvitations() {
  260.         return false;
  261.     },
  262.  
  263.     get canRefresh() { return true; },
  264.     refresh: function calWcapCalendar_refresh() {
  265.         log("refresh.", this);
  266.         // invalidate cached results:
  267.         delete this.m_cachedResults;
  268.         // notify about refreshed calendar:
  269.         this.notifyObservers("onLoad", [this]);
  270.     },
  271.     
  272.     issueNetworkRequest: function calWcapCalendar_issueNetworkRequest(
  273.         request, respFunc, dataConvFunc, wcapCommand, params, accessRights)
  274.     {
  275.         var this_ = this;
  276.         // - bootstrap problem: no cal_props, no access check, no default calId
  277.         // - assure being logged in, thus the default cal_props are available
  278.         // - every subscribed calendar will come along with cal_props
  279.         return this.session.getSessionId(
  280.             request,
  281.             function getSessionId_resp(err, sessionId) {
  282.                 try {
  283.                     if (err)
  284.                         throw err;
  285.                     this_.assureAccess(accessRights);
  286.                     params += ("&calid=" + encodeURIComponent(this_.calId));
  287.                     this_.session.issueNetworkRequest(
  288.                         request, respFunc, dataConvFunc, wcapCommand, params);
  289.                 }
  290.                 catch (exc) {
  291.                     respFunc(exc);
  292.                 }
  293.             });
  294.     },
  295.     
  296.     // calIWcapCalendar:
  297.     
  298.     m_session: null,
  299.     get session() {
  300.         if (!this.m_session) {
  301.             var uri = this.uri;
  302.             ASSERT(uri, "no URI set!");
  303.             var path = uri.path;
  304.             var qmPos = path.indexOf("?");
  305.             if (qmPos != -1) {
  306.                 uri = uri.clone();
  307.                 uri.path = path.substring(0, qmPos); // get rid of params
  308.             }
  309.             this.m_session = getWcapSessionFor(this, uri);
  310.         }
  311.         return this.m_session;
  312.     },
  313.  
  314.     m_calId: null,
  315.     get calId() {
  316.         if (this.m_calId)
  317.             return this.m_calId;
  318.         return this.session.defaultCalId;
  319.     },
  320.     
  321.     get ownerId() {
  322.         var ar = this.getCalProps("X-NSCP-CALPROPS-PRIMARY-OWNER");
  323.         if (ar.length == 0) {
  324.             var calId = this.calId;
  325.             log("cannot determine primary owner of calendar " + calId, this);
  326.             // fallback to calId prefix:
  327.             var nColon = calId.indexOf(":");
  328.             if (nColon >= 0)
  329.                 calId = calId.substring(0, nColon);
  330.             return calId;
  331.         }
  332.         return ar[0];
  333.     },
  334.     
  335.     get description() {
  336.         var ar = this.getCalProps("X-NSCP-CALPROPS-DESCRIPTION");
  337.         if (ar.length == 0) {
  338.             // fallback to display name:
  339.             return this.displayName;
  340.         }
  341.         return ar[0];
  342.     },
  343.     
  344.     get displayName() {
  345.         var ar = this.getCalProps("X-NSCP-CALPROPS-NAME");
  346.         if (ar.length == 0) {
  347.             // fallback to common name:
  348.             ar = this.getCalProps("X-S1CS-CALPROPS-COMMON-NAME");
  349.             if (ar.length == 0) {
  350.                 ar = [this.calId];
  351.             }
  352.         }
  353.         var name = ar[0];
  354.         var defaultCal = this.session.defaultCalendar;
  355.         if (defaultCal) {
  356.             var defName = (getCalendarManager().getCalendarPref(defaultCal, "account_name") ||
  357.                            getCalendarManager().getCalendarPref(defaultCal, "name"));
  358.             if (defName) {
  359.                 name += (" (" + defName + ")");
  360.             }
  361.         }
  362.         return name;
  363.     },
  364.     
  365.     get isOwnedCalendar() {
  366.         if (this.isDefaultCalendar)
  367.             return true; // default calendar is owned
  368.         return (this.ownerId == this.session.userId);
  369.     },
  370.     
  371.     get isDefaultCalendar() {
  372.         return !this.m_calId;
  373.     },
  374.     
  375.     getCalendarProperties: function calWcapCalendar_getCalendarProperties(propName, out_count) {
  376.         var ret = this.getCalProps(propName);
  377.         out_count.value = ret.length;
  378.         return ret;
  379.     },
  380.  
  381.     m_calProps: null,
  382.     getCalProps: function calWcapCalendar_getCalProps(propName) {
  383.         if (!this.m_calProps) {
  384.             log("soft error: no calprops, most possibly not logged in.", this);
  385. //             throw new Components.Exception("No calprops available!",
  386. //                                            Components.results.NS_ERROR_NOT_AVAILABLE);
  387.         }
  388.         return filterXmlNodes(propName, this.m_calProps);
  389.     },
  390.     
  391.     get defaultTimezone() {
  392.         var tzid = this.getCalProps("X-NSCP-CALPROPS-TZID");
  393.         if (tzid.length == 0) {
  394.             logError("defaultTimezone: cannot get X-NSCP-CALPROPS-TZID!", this);
  395.             return "UTC"; // fallback
  396.         }
  397.         return tzid[0];
  398.     },
  399.     
  400.     getAlignedTimezone: function calWcapCalendar_getAlignedTimezone(tzid) {
  401.         // check whether it is one of cs:
  402.         if (tzid.indexOf("/mozilla.org/") == 0) {
  403.             // cut mozilla prefix: assuming that the latter string portion
  404.             //                     semantically equals the demanded timezone
  405.             tzid = tzid.substring( // next slash after "/mozilla.org/"
  406.                 tzid.indexOf("/", "/mozilla.org/".length) + 1);
  407.         }
  408.         if (!this.session.isSupportedTimezone(tzid)) {
  409.             // xxx todo: we could further on search for a matching region,
  410.             //           e.g. CET (in TZNAME), but for now stick to
  411.             //           user's default if not supported directly
  412.             var ret = this.defaultTimezone;
  413.             // use calendar's default:
  414.             log(tzid + " not supported, falling back to default: " + ret, this);
  415.             return ret;
  416.         }
  417.         else // is ok (supported):
  418.             return tzid;
  419.     },
  420.     
  421.     checkAccess: function calWcapCalendar_checkAccess(accessControlBits)
  422.     {
  423.         // xxx todo: take real acl into account
  424.         // for now, optimistically assuming that everybody has full access, server will check:
  425.         var granted = calIWcapCalendar.AC_FULL;
  426.         if (this.m_bReadOnly) {
  427.             granted &= ~(calIWcapCalendar.AC_COMP_WRITE |
  428.                          calIWcapCalendar.AC_PROP_WRITE);
  429.         }
  430.         // check whether every bit fits:
  431.         return ((accessControlBits & granted) == accessControlBits);
  432.     },
  433.     
  434.     assureAccess: function calWcapCalendar_assureAccess(accessControlBits)
  435.     {
  436.         if (!this.checkAccess(accessControlBits & (calIWcapCalendar.AC_COMP_WRITE |
  437.                                                    calIWcapCalendar.AC_PROP_WRITE))) {
  438.             // throw different error code for read-only:
  439.             throw new Components.Exception("Access denied!",
  440.                                            calIErrors.CAL_IS_READONLY);
  441.         }
  442.         if (!this.checkAccess(accessControlBits)) {
  443.             throw new Components.Exception("Access denied!",
  444.                                            calIWcapErrors.WCAP_ACCESS_DENIED_TO_CALENDAR);
  445.             // xxx todo: throwing different error here, no
  446.             //           calIErrors.CAL_IS_READONLY anymore
  447.         }
  448.     },
  449.     
  450.     defineAccessControl: function calWcapCalendar_defineAccessControl(
  451.         userId, accessControlBits)
  452.     {
  453.         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  454.     },
  455.     
  456.     resetAccessControl: function calWcapCalendar_resetAccessControl(userId)
  457.     {
  458.         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  459.     },
  460.     
  461.     getAccessControlDefinitions: function calWcapCalendar_getAccessControlDefinitions(
  462.         out_count, out_users, out_accessControlBits)
  463.     {
  464.         throw Components.results.NS_ERROR_NOT_IMPLEMENTED;
  465.     }
  466. };
  467.  
  468.